﻿using mozhi.smarterp.Business.Enums;
using Mozhi.Abp.Domain.AuthorCenter;
using Mozhi.Abp.Domain.BasicData;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp;

namespace mozhi.smarterp.Business.Purchases
{
    /// <summary>
    /// 采购申请单
    /// </summary>
    public class PurchaseRequisition : DocumentAggregateRoot<PurchaseRequisitionItem>
    {
        /// <summary>
        /// 产品类型
        /// </summary>
        public ProductType ProductType { get; private set; }

        public decimal TotalQuantity { get; private set; }

        public decimal? OrderQuantity { get; private set; }

        public decimal RemainingQuantity
        {
            get
            {
                return TotalQuantity - (OrderQuantity ?? 0);
            }
        }

        /// <summary>
        /// 申请人
        /// </summary>
        public Guid? ApplicantId { get; private set; }

        public Employee Applicant { get; private set; }

        private PurchaseRequisition() { }

        public PurchaseRequisition(Guid id, string number, DateTime date, string comment, ProductType productType, Currency currency, bool includeTax,
            Department department, Employee applicant) : base(id, number, date, includeTax, currency, currency?.ExchangeRate ?? 0, department, comment)
        {
            Currency = currency;
            Applicant = applicant;
            Department = department;

            Id = id;
            Number = number;
            Date = date;
            Comment = comment;
            ProductType = productType;
            CurrencyId = currency == null ? default : currency.Id;
            ExchangeRate = currency == null ? default : currency.ExchangeRate;
            DepartmentId = Department?.Id;
            ApplicantId = Applicant?.Id;
            IncludeTax = includeTax;

            Items = new List<PurchaseRequisitionItem>();
            Validate();
        }

        public void Change(string number, DateTime date, string comment, ProductType productType, Currency currency, bool includeTax, Department department, Employee applicant)
        {
            ValidateStatus();

            Currency = currency;
            Applicant = applicant;
            Department = department;

            Number = number;
            Date = date;
            Comment = comment;
            ProductType = productType;
            CurrencyId = currency == null ? default : currency.Id;
            ExchangeRate = currency == null ? default : currency.ExchangeRate;
            DepartmentId = Department?.Id;
            ApplicantId = Applicant?.Id;
            IncludeTax = includeTax;

            Validate();
        }

        public override void ChangeItems(List<PurchaseRequisitionItem> items)
        {
            base.ChangeItems(items);

            TotalQuantity = Items.Sum(x => x.BasicQuantity);
        }



        #region
        protected override void Validate()
        {
            base.Validate();

            if (Applicant != null)
                Applicant.Validate();

            Check.NotDefaultOrNull<ProductType>(ProductType, nameof(ProductType));
        }



        protected override void AddOrUpdateItem(PurchaseRequisitionItem item)
        {
            if (ProductType != (ProductType)item.Product.Type)
                throw new UserFriendlyException($"不允许新增类型为{item.Product.Type}的产品", "100000");

            var match = Items.FirstOrDefault(x => x.Id == item.Id);

            if (match == null && Status != DocumentStatusType.Creation)
                throw new UserFriendlyException($"单据已提交，不允许新增分录", "100000");

            if (match == null)
            {
                match = item;

                var approvedQuantity = Status == DocumentStatusType.Creation ? item.AuxiliaryQuantity : item.ApprovedQuantity;

                match.SetApprovedQuantity(approvedQuantity);

                match.CalculateBaiscUnitQuantity();
                match.CalculateAmount(IncludeTax, ExchangeRate);
                Items.Add(match);
            }
            else
            {
                if (Status == DocumentStatusType.PendingApproval)
                {
                    //提交审核的单据只能更改建议供应商和审核数量，单价，税率等信息

                    match.SetApprovedQuantity(item.ApprovedQuantity);
                    match.SetSuggestedSupplier(item.SuggestedSupplier);
                    match.SetPrice(item.Price);
                    match.SetTaxRate(item.TaxRate);
                }
                else
                {
                    //创建的单据审核数量是等于申请数量的
                    var approvedQuantity = Status == DocumentStatusType.Creation ? item.AuxiliaryQuantity : item.ApprovedQuantity;

                    match.Change(item.Product, item.AuxiliaryUnit, item.ProductAuxiliaryUnit, item.AuxiliaryQuantity, approvedQuantity, item.Price, item.TaxRate,
                                       item.RequiredDate, item.SuggestedSupplier, item.Remark);
                }

                match.CalculateBaiscUnitQuantity();
                match.CalculateAmount(IncludeTax, ExchangeRate);
            }
        }

        protected override void ValidateStatus()
        {
            //采购申请单比较特殊，提交审核阶段，是可以更改审核数量和建议供应商的，所以需要重写校验
            if (Status == DocumentStatusType.Approved)
                throw new UserFriendlyException($"单据：{Number}已审核，不允许进行修改", "100000");

            if (Status == DocumentStatusType.Invalid)
                throw new UserFriendlyException($"单据：{Number}已作废，不允许进行修改", "100000");

            if (Status == DocumentStatusType.Closed)
                throw new UserFriendlyException($"单据：{Number}已关闭，不允许进行修改", "100000");
        }
        #endregion

    }

    public class PurchaseRequisitionItem : DocumentEntity
    {
        /// <summary>
        /// 批准数量
        /// </summary>
        public decimal ApprovedQuantity { get; private set; }

        /// <summary>
        ///要货日期
        /// </summary>
        public DateTime? RequiredDate { get; private set; }

        /// <summary>
        /// 建议供应商
        /// </summary>
        public Guid? SuggestedSupplierId { get; private set; }

        public Supplier SuggestedSupplier {  get; private set; }

        private PurchaseRequisitionItem() { }

        public PurchaseRequisitionItem(Guid id, Product product, Unit requisitionUnit, ProductAuxiliaryUnit auxiliaryUnit , decimal requisitionQuantity, decimal approvedQuantity,
            decimal price , TaxRate taxRate,  DateTime? requiredDate, Supplier suggestedSupplier, string remark): base(id, product, requisitionUnit, auxiliaryUnit, requisitionQuantity, price, taxRate, remark)
        {
            Id = id;

            RequiredDate = requiredDate;

            Change(product, requisitionUnit, auxiliaryUnit, requisitionQuantity, approvedQuantity,
             price, taxRate, requiredDate, suggestedSupplier, remark);

            Remark = remark;

            Validate();
        }

        public void Change(Product product, Unit requisitionUnit, ProductAuxiliaryUnit auxiliaryUnit, decimal requisitionQuantity, decimal approvedQuantity,
            decimal price, TaxRate taxrate, DateTime? requiredDate, Supplier suggestedSupplier, string remark)
        {
            base.Change(product, requisitionUnit, auxiliaryUnit, requisitionQuantity, price, taxrate, remark);

            SetSuggestedSupplier(suggestedSupplier);

            RequiredDate = requiredDate;

            SetApprovedQuantity(approvedQuantity);

            Remark = remark;

            Validate();
        }

        public void SetSuggestedSupplier(Supplier suggestedSupplier)
        {
            SuggestedSupplier = suggestedSupplier;
            SuggestedSupplierId = SuggestedSupplier?.Id;

            ValidateSuggestedSupplier();
        }

        public void SetApprovedQuantity(decimal approvedQuantity)
        {
            if (approvedQuantity <= 0)
                throw new UserFriendlyException("审批数量必须大于0", "100000");

            ApprovedQuantity = approvedQuantity;
        }

        public void SetTaxRate(TaxRate taxRate)
        {
            if (taxRate == null)
                return;

            taxRate.Validate();

            TaxRate = taxRate;
            TaxRateId = taxRate.Id;
            TaxRateValue = taxRate.Rate;

        }

        public void SetPrice(decimal price)
        {
            Price = price;
        }

        #region
        protected override void Validate()
        {
            base.Validate();

            if (AuxiliaryQuantity <= 0)
                throw new UserFriendlyException("申请数量必须大于0", "100000");

            if (ApprovedQuantity <= 0)
                throw new UserFriendlyException("批准数量必须大于0", "100000");

            if (ApprovedQuantity > AuxiliaryQuantity)
                throw new UserFriendlyException("批准数量不能大于申请数量", "100000");

            if (Price < 0)
                throw new UserFriendlyException("单价必须大于0", "100000");

            Check.NotDefaultOrNull<Guid>(BasicUnitId, nameof(BasicUnitId));
        }

        private void ValidateSuggestedSupplier()
        {
            if (SuggestedSupplier == null)
                return;

            SuggestedSupplier.Validate();
        }
        #endregion
    }
}
